//
// Created by 29108 on 2025/6/29.
//

#ifndef LOGGER_H
#define LOGGER_H

// 防止宏冲突，在包含系统头文件之前取消可能冲突的宏定义
#ifdef DEBUG
#undef DEBUG
#endif
#ifdef INFO
#undef INFO
#endif
#ifdef WARNING
#undef WARNING
#endif
#ifdef ERROR
#undef ERROR
#endif

#include <string>
#include <fstream>
#include <iostream>
#include <mutex>
#include <memory>
#include <vector>
#include <thread>
#include <condition_variable>
#include <queue>
#include <atomic>
#include <chrono>
#include <iomanip>
#include <sstream>
#include <ctime>
#include "./common/config/config_manager.h"
#include "./common/thread_pool/thread_pool.h"



using namespace common::config;
namespace common {
    namespace logger {


        // // 日志级别
        // enum class LogLevel {
        //     LOG_DEBUG,
        //     LOG_INFO,
        //     LOG_WARNING,
        //     LOG_ERROR,
        //     LOG_FATAL   //毁灭的
        // };

        // 日志条目
        struct LogEntry {
            std::string message;
            LogLevel level;
            std::chrono::system_clock::time_point timestamp;
            std::thread::id threadId;
            const char* file;  // 文件名
            int line;          // 行号

            LogEntry(const std::string& msg, LogLevel lvl, const char* file, int line)
                : message(msg), level(lvl),
                  timestamp(std::chrono::system_clock::now()),
                  threadId(std::this_thread::get_id()),
                  file(file), line(line) {}
        };

        // 日志输出接口
        class LogSink {
        public:
            virtual ~LogSink() = default;
            virtual void write(const LogEntry& entry) = 0;
            virtual void flush() = 0;
        };

        // 控制台日志输出
        class ConsoleSink : public LogSink {
        public:
            void write(const LogEntry& entry) override;
            void flush() override { std::cout.flush(); }
        };

        // 文件日志输出
        class FileSink : public LogSink {
        public:
            FileSink(const std::string& filename);
            ~FileSink();

            void write(const LogEntry& entry) override;
            void flush() override;

        private:
            std::ofstream file_;
            std::mutex fileMutex_;
        };

        // 日志管理类
        class Logger {
        public:

            struct Config {
                // ==================== 日志级别配置 ====================
                LogLevel level = LogLevel::INFO;

                // ==================== 控制台日志配置 ====================
                bool console_enabled = true;
                bool console_colored = true;
                LogLevel console_level = LogLevel::DEBUG;
                std::string console_pattern = "[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%t] [%s:%#] %v";

                // ==================== 文件日志配置 ====================
                bool file_enabled = true;
                std::string file_path = "./logs/game_service.log";
                LogLevel file_level = LogLevel::INFO;
                size_t file_max_size = 104857600; // 100MB
                int file_max_files = 10;
                std::string file_rotation_policy = "size";
                std::string file_rotation_time = "00:00";
                bool file_compression = true;

                // ==================== 异步日志配置 ====================
                bool async_enabled = false;
                size_t async_queue_size = 10000;

                // ==================== ThreadPool集成配置 ====================
                bool use_thread_pool = true;                    ///< 是否使用ThreadPool进行异步处理
                int thread_pool_core_size = 2;                  ///< ThreadPool核心线程数
                int thread_pool_max_size = 4;                   ///< ThreadPool最大线程数
                int thread_pool_queue_capacity = 5000;          ///< ThreadPool队列容量
                bool enable_thread_pool_monitoring = false;     ///< 是否启用ThreadPool监控
                bool parallel_sink_processing = true;           ///< 是否并行处理多个Sink
                int batch_processing_size = 50;                 ///< 批量处理大小

                // ==================== ConfigManager集成方法 ====================
                /**
                 * @brief 从ConfigManager加载日志配置
                 */
                static Config fromConfigManager() {
                    auto& config = ConfigManager::getInstance();
                    Config result;

                    // 全局日志级别
                    std::string level_str = config.get<std::string>("logging.level", "LOG_INFO");
                    result.level = Logger::stringToLogLevel(level_str);

                    // 控制台日志配置
                    result.console_enabled = config.get<bool>("logging.console.enabled", true);
                    result.console_colored = config.get<bool>("logging.console.colored", true);
                    std::string console_level_str = config.get<std::string>("logging.console.level", "LOG_DEBUG");
                    result.console_level = Logger::stringToLogLevel(console_level_str);
                    result.console_pattern = config.get<std::string>("logging.console.pattern",
                        "[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [%t] [%s:%#] %v");

                    // 文件日志配置
                    result.file_enabled = config.get<bool>("logging.file.enabled", true);
                    result.file_path = config.get<std::string>("logging.file.path", "./logs/game_service.log");
                    std::string file_level_str = config.get<std::string>("logging.file.level", "LOG_INFO");
                    result.file_level = Logger::stringToLogLevel(file_level_str);
                    result.file_max_size = config.get<size_t>("logging.file.max_size", 104857600);
                    result.file_max_files = config.get<int>("logging.file.max_files", 10);
                    result.file_rotation_policy = config.get<std::string>("logging.file.rotation_policy", "size");
                    result.file_rotation_time = config.get<std::string>("logging.file.rotation_time", "00:00");
                    result.file_compression = config.get<bool>("logging.file.compression", true);

                    // 异步日志配置
                    result.async_enabled = config.get<bool>("logging.async.enabled", false);
                    result.async_queue_size = config.get<size_t>("logging.async.queue_size", 10000);

                    // ThreadPool集成配置
                    result.use_thread_pool = config.get<bool>("logging.thread_pool.enabled", true);
                    result.thread_pool_core_size = config.get<int>("logging.thread_pool.core_size", 2);
                    result.thread_pool_max_size = config.get<int>("logging.thread_pool.max_size", 4);
                    result.thread_pool_queue_capacity = config.get<int>("logging.thread_pool.queue_capacity", 5000);
                    result.enable_thread_pool_monitoring = config.get<bool>("logging.thread_pool.enable_monitoring", false);
                    result.parallel_sink_processing = config.get<bool>("logging.thread_pool.parallel_sink_processing", true);
                    result.batch_processing_size = config.get<int>("logging.thread_pool.batch_processing_size", 50);

                    return result;
                }

                /**
                 * @brief 验证日志配置
                 */
                void validate() const {
                    if (file_enabled && file_path.empty()) {
                        throw std::runtime_error("File logging enabled but file path is empty");
                    }
                    if (file_max_size == 0) {
                        throw std::runtime_error("File max size must be greater than 0");
                    }
                    if (file_max_files <= 0) {
                        throw std::runtime_error("File max files must be greater than 0");
                    }
                    if (async_queue_size == 0) {
                        throw std::runtime_error("Async queue size must be greater than 0");
                    }
                }
            };
            static Logger& getInstance();

            // 添加日志接收器
            void addSink(std::shared_ptr<LogSink> sink);

            // 移除日志接收器
            void removeSink(std::shared_ptr<LogSink> sink);

            // 清空所有日志接收器
            void clearSinks();

            // 设置全局日志级别
            void setLevel(LogLevel level) { level_ = level; }

            // 获取当前日志级别
            LogLevel getLevel() const { return level_; }

            /**
            * @brief 使用ConfigManager配置初始化Logger
            * @note 必须在ConfigManager完全初始化后调用，避免循环依赖
            */
            void initializeFromConfig();

            /**
             * @brief 检查是否已从配置初始化
             */
            bool isInitializedFromConfig() const { return config_initialized_; }

            /**
             * @brief 启用配置热更新监听
             */
            void enableConfigHotReload();

            /**
             * @brief 获取ThreadPool状态信息
             * @return ThreadPool状态字符串，如果未使用ThreadPool则返回空字符串
             */
            std::string getThreadPoolStatus() const;

            /**
             * @brief 获取ThreadPool活跃线程数
             * @return 活跃线程数，如果未使用ThreadPool则返回0
             */
            size_t getActiveThreadCount() const;

            /**
             * @brief 获取ThreadPool队列大小
             * @return 队列大小，如果未使用ThreadPool则返回0
             */
            size_t getThreadPoolQueueSize() const;

            /**
             * @brief 动态调整ThreadPool大小
             * @param core_size 新的核心线程数
             * @param max_size 新的最大线程数
             * @return 是否调整成功
             */
            bool adjustThreadPoolSize(int core_size, int max_size);

            /**
             * @brief 强制刷新所有待处理的日志
             * @details 等待ThreadPool中的所有任务完成
             */
            void forceFlush();

            // 日志记录函数
            void log(LogLevel level, const std::string& message, const char* file, int line);
            void debug(const std::string& message, const char* file, int line) { log(LogLevel::DEBUG, message, file, line); }
            void info(const std::string& message, const char* file, int line) { log(LogLevel::INFO, message, file, line); }
            void warning(const std::string& message, const char* file, int line) { log(LogLevel::WARNING, message, file, line); }
            void error(const std::string& message, const char* file, int line) { log(LogLevel::ERROR, message, file, line); }
            void fatal(const std::string& message, const char* file, int line) { log(LogLevel::FATAL, message, file, line); }

            // 启动异步日志线程
            void startAsync();

            // 停止异步日志线程
            void stopAsync();

            // 检查异步日志是否启用
            bool isAsyncEnabled() const { return async_enabled_.load(); }

            // 刷新所有输出
            void flushAll();

            // 析构函数
            ~Logger();

            // 将日志级别转换为字符串
            static std::string levelToString(LogLevel level);
            static LogLevel stringToLogLevel(const std::string& level_str);

            // 格式化时间戳
            static std::string formatTimestamp(const std::chrono::system_clock::time_point& time);

        private:
            // 私有构造函数
            Logger();

            Config config_;
            std::vector<std::shared_ptr<LogSink>> sinks_;  // 日志接收器
            std::mutex sinkMutex_;                        // 保护接收器的互斥锁
            LogLevel level_;                              // 全局日志级别

            // 异步日志相关
            std::queue<LogEntry> async_queue_;                   ///< 异步消息队列
            std::thread async_thread_;                             ///< 异步处理线程
            std::mutex async_mutex_;                               ///< 异步队列互斥锁
            std::condition_variable async_condition_;

            // 移除重复的级别变量，统一使用level_
            std::atomic<bool> async_enabled_{false};               ///< 异步日志是否启用
            std::atomic<bool> async_stop_flag_{false};             ///< 异步线程停止标志
            size_t async_queue_size_ = 10000;                      ///< 异步队列大小
            std::atomic<bool> config_initialized_{false};          ///< 是否已从配置初始化

            /// @brief ThreadPool实例（用于并行日志处理）
            std::unique_ptr<common::thread_pool::ThreadPool> thread_pool_;

            /// @brief ThreadPool处理统计
            std::atomic<uint64_t> thread_pool_tasks_submitted_{0};
            std::atomic<uint64_t> thread_pool_tasks_completed_{0};

            void reinitializeFileSink(const std::string& new_path);

            /**
            * @brief 动态调整日志级别
            * @param new_level 新的日志级别
            * @details 立即生效的日志级别调整
            */
            void adjustLogLevel(LogLevel new_level);

            /**
             * @brief 动态调整控制台日志设置
             * @param enabled 是否启用控制台日志
             * @param colored 是否启用彩色输出
             */
            void adjustConsoleSettings(bool enabled, bool colored);

            /**
             * @brief 动态调整异步日志设置
             * @param enabled 是否启用异步日志
             * @param queue_size 异步队列大小
             */
            void adjustAsyncSettings(bool enabled, size_t queue_size);

            /**
             * @brief 初始化ThreadPool
             * @details 根据配置创建和配置ThreadPool
             */
            void initializeThreadPool();

            /**
             * @brief 关闭ThreadPool
             * @details 安全关闭ThreadPool并等待任务完成
             */
            void shutdownThreadPool();

            /**
             * @brief 使用ThreadPool处理日志条目
             * @param entry 日志条目
             */
            void processLogEntryWithThreadPool(const LogEntry& entry);

            /**
             * @brief 批量处理日志条目
             * @param entries 日志条目批次
             */
            void processBatchLogEntries(const std::vector<LogEntry>& entries);

            /**
             * @brief 并行处理单个日志条目到所有Sink
             * @param entry 日志条目
             */
            void processLogEntryParallel(const LogEntry& entry);

            /**
             * @brief 异步日志工作线程
             */
            void asyncWorker() ;

            /**
             * @brief 处理单个日志消息
             * @param message 日志消息
             */
            void processLogMessage(const LogEntry& message);
        };

        // 宏定义，方便使用
#define LOG_DEBUG(message) common::logger::Logger::getInstance().debug(message, __FILE__, __LINE__ )
#define LOG_INFO(message) common::logger::Logger::getInstance().info(message, __FILE__, __LINE__ )
#define LOG_WARNING(message) common::logger::Logger::getInstance().warning(message, __FILE__, __LINE__ )
#define LOG_ERROR(message) common::logger::Logger::getInstance().error(message, __FILE__, __LINE__ )
#define LOG_FATAL(message) common::logger::Logger::getInstance().fatal(message, __FILE__, __LINE__ )

    } // namespace logger
}

#endif // LOGGER_H